]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
shell/app-system: Monitor for icon theme changes
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>
Thu, 1 Aug 2019 23:58:20 +0000 (20:58 -0300)
committerFlorian Müllner <florian.muellner@gmail.com>
Thu, 8 Aug 2019 15:22:44 +0000 (15:22 +0000)
Whenever an app is installed, the usual routine is
to run 'gtk-update-icon-cache' after installing all
of the app's files.

The side effect of that is that the .desktop file of
the application is installed before the icon theme
is updated. By the time GAppInfoMonitor emits the
'changed' signal, the icon theme is not yet updated,
leading to StIcon use the fallback icon.

Under some circumstances (e.g. on very slow spinning
disks) the app icon is never actually loaded, and we
see the fallback icon forever.

Monitor the icon theme for changes when an app is
installed. Try as many as 6 times before giving up
on detecting an icon theme update.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/661

src/shell-app-system.c
src/st/st-texture-cache.c
src/st/st-texture-cache.h

index f632cbe545ee6c68a66ca0e7fcf8cdab0eb6060b..127f29ef02a12f705009d69b8bee574e3b4bf527 100644 (file)
 #include "shell-app-system-private.h"
 #include "shell-global.h"
 #include "shell-util.h"
+#include "st.h"
+
+/* Rescan for at most RESCAN_TIMEOUT_MS * MAX_RESCAN_RETRIES. That
+ * should be plenty of time for even a slow spinning drive to update
+ * the icon cache.
+ */
+#define RESCAN_TIMEOUT_MS 2500
+#define MAX_RESCAN_RETRIES 6
 
 /* Vendor prefixes are something that can be preprended to a .desktop
  * file name.  Undo this.
@@ -51,6 +59,9 @@ struct _ShellAppSystemPrivate {
   GHashTable *id_to_app;
   GHashTable *startup_wm_class_to_id;
   GList *installed_apps;
+
+  guint rescan_icons_timeout_id;
+  guint n_rescan_retries;
 };
 
 static void shell_app_system_finalize (GObject *object);
@@ -157,12 +168,54 @@ stale_app_remove_func (gpointer key,
   return app_is_stale (value);
 }
 
+static gboolean
+rescan_icon_theme_cb (gpointer user_data)
+{
+  ShellAppSystemPrivate *priv;
+  ShellAppSystem *self;
+  StTextureCache *texture_cache;
+  gboolean rescanned;
+
+  self = (ShellAppSystem *) user_data;
+  priv = self->priv;
+
+  texture_cache = st_texture_cache_get_default ();
+  rescanned = st_texture_cache_rescan_icon_theme (texture_cache);
+
+  priv->n_rescan_retries++;
+
+  if (rescanned || priv->n_rescan_retries >= MAX_RESCAN_RETRIES)
+    {
+      priv->n_rescan_retries = 0;
+      priv->rescan_icons_timeout_id = 0;
+      return G_SOURCE_REMOVE;
+    }
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+rescan_icon_theme (ShellAppSystem *self)
+{
+  ShellAppSystemPrivate *priv = self->priv;
+
+  priv->n_rescan_retries = 0;
+
+  if (priv->rescan_icons_timeout_id > 0)
+    return;
+
+  priv->rescan_icons_timeout_id = g_timeout_add (RESCAN_TIMEOUT_MS,
+                                                 rescan_icon_theme_cb,
+                                                 self);
+}
+
 static void
 installed_changed (GAppInfoMonitor *monitor,
                    gpointer         user_data)
 {
   ShellAppSystem *self = user_data;
 
+  rescan_icon_theme (self);
   scan_startup_wm_class_to_id (self);
 
   g_hash_table_foreach_remove (self->priv->id_to_app, stale_app_remove_func, NULL);
@@ -200,6 +253,7 @@ shell_app_system_finalize (GObject *object)
   g_hash_table_destroy (priv->id_to_app);
   g_hash_table_destroy (priv->startup_wm_class_to_id);
   g_list_free_full (priv->installed_apps, g_object_unref);
+  g_clear_handle_id (&priv->rescan_icons_timeout_id, g_source_remove);
 
   G_OBJECT_CLASS (shell_app_system_parent_class)->finalize (object);
 }
index bf54c651402e3b04bb88f4925c312d6e6f267b2e..53df7195b8d3d66c43c647adecb6a4728878c45b 100644 (file)
@@ -1567,3 +1567,11 @@ st_texture_cache_get_default (void)
     instance = g_object_new (ST_TYPE_TEXTURE_CACHE, NULL);
   return instance;
 }
+
+gboolean
+st_texture_cache_rescan_icon_theme (StTextureCache *cache)
+{
+  StTextureCachePrivate *priv = cache->priv;
+
+  return gtk_icon_theme_rescan_if_needed (priv->icon_theme);
+}
index 11d1c4e640bfc1796ea4f2dc5bb6aea3a4d54131..a99316da8f6302c1944328ab2ed22bb639be6346 100644 (file)
@@ -113,4 +113,6 @@ CoglTexture * st_texture_cache_load (StTextureCache       *cache,
                                      void                 *data,
                                      GError              **error);
 
+gboolean st_texture_cache_rescan_icon_theme (StTextureCache *cache);
+
 #endif /* __ST_TEXTURE_CACHE_H__ */